package com.nemesis.android.helloworld;

import android.content.Context;
import android.graphics.Canvas;
import android.hardware.CameraDevice;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

//----------------------------------------------------------------------

public class Preview extends SurfaceView implements SurfaceHolder.Callback {
    SurfaceHolder  mHolder;
    private PreviewThread mPreviewThread;
    private boolean mHasSurface;
    
    Preview(Context context) {
        super(context);
        
        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHasSurface = false;
        
        // In this example, we hardcode the size of the preview. In a real
        // application this should be more dynamic. This guarantees that
        // the uderlying surface will never change size.
        mHolder.setFixedSize(320, 240);
    }

    public void resume() {
        // We do the actual acquisition in a separate thread. Create it now.
        if (mPreviewThread == null) {
            mPreviewThread = new PreviewThread();
            // If we already have a surface, just start the thread now too.
            if (mHasSurface == true) {
                mPreviewThread.start();
            }
        }
    }
    
    public void pause() {
        // Stop Preview.
        if (mPreviewThread != null) {
            mPreviewThread.requestExitAndWait();
            mPreviewThread = null;
        }
    }
    
    public boolean isPaused() {
    	return (mPreviewThread == null);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, start our main acquisition thread.
        mHasSurface = true;
        if (mPreviewThread != null) {
            mPreviewThread.start();
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // Surface will be destroyed when we return. Stop the preview.
        mHasSurface = false;
        pause();
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // Surface size or format has changed. This should not happen in this
        // example.
    }

    // ----------------------------------------------------------------------

    class PreviewThread extends Thread {
        private boolean mDone;
        
        PreviewThread() {
            super();
            mDone = false;
        }
    
        @Override
		public void run() {
            // We first open the CameraDevice and configure it.
            CameraDevice camera = CameraDevice.open();
            if (camera != null) {
                CameraDevice.CaptureParams param = new CameraDevice.CaptureParams();
                    param.type = 1; // preview
                    param.srcWidth      = 1280;
                    param.srcHeight     = 960;
                    param.leftPixel     = 0;
                    param.topPixel      = 0;
                    param.outputWidth   = 320;
                    param.outputHeight  = 240;
                    param.dataFormat    = 2; // RGB_565
                camera.setCaptureParams(param);
            }

            // This is our main acquisition thread's loop, we go until
            // asked to quit.
            SurfaceHolder holder = mHolder;
            while (!mDone) {
                // Lock the surface, this returns a Canvas that can
                // be used to render into.
                Canvas canvas = holder.lockCanvas();

                // Capture directly into the Surface
                if (camera != null) {
                    camera.capture(canvas);
                }
                
                // And finally unlock and post the surface.
                holder.unlockCanvasAndPost(canvas);
            }

            // Make sure to release the CameraDevice
            if (camera != null)
                camera.close();
        }
        
        public void requestExitAndWait() {
            // don't call this from PreviewThread thread or it a guaranteed
            // deadlock!
            mDone = true;
            try {
                join();
            } catch (InterruptedException ex) { }
        }
    }
}